package com.ddt;

import org.jawin.COMException;
import org.jawin.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.qiyou.javaelf.operation.*;
import com.qiyou.javaelf.system.Elf;
import org.springframework.stereotype.Controller;

import java.util.HashMap;
import java.util.Map;


public class MatchColor {
    static final Logger logger = LoggerFactory.getLogger(MatchColor.class);

    private Picture picture;
    private Window window;
    private Keyboard keyboard;
    private Mouse mouse;
    private Background background;
    private Ocr orc;
    private String DmPath;
    private Elf elf;


    public MatchColor(Elf elf){
        this.elf = elf;
        this.picture =  new Picture(elf);
        this.window = new Window(elf);
        this.keyboard = new Keyboard(elf);
        this.background = new Background(elf);
        this.orc = new Ocr(elf);
        this.mouse = new Mouse(elf);
    }


    public int setWindowState(int hwnd, int status){
        Object[] params = new Object[]{hwnd, status};
        int res = 0;
        try {
            res = this.window.SetWindowState(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("SetWindowState: {}", res);
        return res;

    }

    public int bindWindow(int hwnd){
        Object[] params = new Object[]{hwnd, "gdi", "windows", "windows", 0};
        int res = 0;
        try {
            res = Integer.parseInt(elf.execute(Background.class, BackgroundOperations.BindWindow, params).toString());
        }catch (Exception e){
            logger.info("error: {}", e.toString());
        }finally {
            logger.info("BindWindow: {}",res);
        }
        return res;
    }
    public int forceUnBindWindow(int hwnd){
        Object[] params = new Object[]{hwnd};
        int res = 0;
        try {
            res = Integer.parseInt(elf.execute(Background.class, BackgroundOperations.ForceUnBindWindow, params).toString());
        }catch (Exception e){
            logger.info("error: {}", e.toString());
        }finally {
            logger.info("ForceUnBindWindow: {}",res);
        }
        return res;
    }

    public int unBindWindow(){
        Object[] params = new Object[]{};
        int res = 0;
        try {
            res = Integer.parseInt(elf.execute(Background.class, BackgroundOperations.UnBindWindow, params).toString());
        }catch (Exception e){
            logger.info("error: {}", e.toString());
        }finally {
            logger.info("UnBindWindow: {}",res);
        }
        return res;
    }

    public int capture(int x_l, int y_l, int x_r, int y_r, String path){
        Object[] params = new Object[]{x_l, y_l, x_r, y_r, path};
        int res = 0;
        try {
            res = this.picture.Capture(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("Capture: {}",res);
        return res;
    }

    public int clientToScreen(int hwnd, Variant x, Variant y){
        Object[] params = new Object[]{hwnd, x, y};
        int res = 0;
        try {
            res = this.window.ClientToScreen(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("params[1]: {}, params[2]", params[1], params[2]);
        return res;

    }

    public  Map<String, Integer> enumWindow36(){
        Object[] params = new Object[]{0, "", "36JBCOM_Browser", 2};
        String res = "";
        try {
            res = this.window.EnumWindow(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        assert res == "" : "error: 36window is null";

        // 1 2 3 4 5 , 6 7 8
        String[] hwnds = res.split(",");

        // get title of hwnd  title = "[4399-1-test]|1|test|hwnd|*|*"
        Map<String, Integer> users = new HashMap<String, Integer>();
        for(int i = 0; i < hwnds.length; i++){
            String title = this.getWindowTitle(Integer.parseInt(hwnds[i]));
            String name = "";
            int hwnd = 0;
            for(int j = 0; j < 4; j ++ ){
                int index = title.indexOf("|", 1);

                if(j == 2){
                    name = title.substring(1, index);
                }else if(j == 3){
                    hwnd = Integer.parseInt(title.substring(1, index));
                }
                users.put(name, hwnd);
                title = title.substring(index);
            }

        }

        return users;

    }

    public String getWindowTitle(int hwnd){
        Object[] params = new Object[]{hwnd};
        String res = "";
        try {
            res = this.window.GetWindowTitle(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        return res;
    }

    public int moveTo(int x, int y){
        Object[] params = new Object[]{x, y};
        int res = 0;
        try {
            res = this.mouse.MoveTo(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("MoveTo: {},{}, res: {}", x, y, res);
        return res;
    }

    public int leftClick(){
        Object[] params = new Object[]{};
        int res = 0;
        try {
            res = this.mouse.LeftClick(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("leftClick:  res: {}", res);
        return res;
    }

    public void click(int x, int y){
        this.moveTo(x, y);
        this.leftClick();
    }
    public void click(String bmp){
        Object[] params = new Object[]{0, 0, 1004, 628, bmp, "000000-000000", 0.5, 0, 0, 0};
        int res = 0;
        try {
            res = this.picture.FindPic(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("find bmp: {}, {}", params[8], params[9]);
        this.click(Integer.parseInt(String.valueOf(params[8])), Integer.parseInt(String.valueOf(params[9])));
    }

    public int getClientSize(int hwnd){
        int weight = 0, height = 0;
        Object[] params = new Object[]{hwnd, weight, height};

        int res = 0;
        try {
            res = this.window.GetClientSize(params);
        } catch (COMException e) {
            logger.info("error: {}", e.toString());
        }
        logger.info("leftClick: {},{}, res{}", params[1], params[2], res);
        return res;
    }

    public Picture getPicture() {
        return picture;
    }

    public void setPicture(Picture picture) {
        this.picture = picture;
    }

    public Window getWindow() {
        return window;
    }

    public void setWindow(Window window) {
        this.window = window;
    }

    public Keyboard getKeyboard() {
        return keyboard;
    }

    public void setKeyboard(Keyboard keyboard) {
        this.keyboard = keyboard;
    }

    public Mouse getMouse() {
        return mouse;
    }

    public void setMouse(Mouse mouse) {
        this.mouse = mouse;
    }

    public Background getBackground() {
        return background;
    }

    public void setBackground(Background background) {
        this.background = background;
    }

    public Ocr getOrc() {
        return orc;
    }

    public void setOrc(Ocr orc) {
        this.orc = orc;
    }

    public String getDmPath() {
        return DmPath;
    }

    public void setDmPath(String dmPath) {
        DmPath = dmPath;
    }
}
